/*
* Copyright (c) 2014 Qunar.com. All Rights Reserved.
*/
package net.oschina.bilbodai.common.beanutil.property.asm.lexer.code.mp;

import org.objectweb.asm.MethodVisitor;

import java.util.List;

import static org.objectweb.asm.Opcodes.BIPUSH;
import static org.objectweb.asm.Opcodes.ICONST_0;
import static org.objectweb.asm.Opcodes.ICONST_1;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;

/**
 * @author qt-maodai  Date: 15-8-8 Time: 下午10:31
 * @version $Id$
 */
public enum MapKeyType {
    ByteType {
        @Override
        public void apply(MethodVisitor mv, String value) {
            Byte key = Byte.valueOf(value);
            mv.visitIntInsn(BIPUSH, key);
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
        }

        @Override
        public Class<?> type() {
            return Byte.class;
        }
    },
    ShortType {
        @Override
        public void apply(MethodVisitor mv, String value) throws NumberFormatException {
            Short key = Short.valueOf(value);
            mv.visitIntInsn(BIPUSH, key);
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
        }

        @Override
        public Class<?> type() {
            return Short.class;
        }
    },
    IntType {
        @Override
        public void apply(MethodVisitor mv, String value) throws NumberFormatException {
            Integer key = Integer.valueOf(value);
            mv.visitIntInsn(BIPUSH, key);
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
        }

        @Override
        public Class<?> type() {
            return Integer.class;
        }
    },
    LongType {
        @Override
        public void apply(MethodVisitor mv, String value) throws NumberFormatException {
            Long key = Long.valueOf(value);
            mv.visitLdcInsn(key);
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
        }

        @Override
        public Class<?> type() {
            return Long.class;
        }
    },
    FloatType {
        @Override
        public void apply(MethodVisitor mv, String value) throws NumberFormatException {
            Float key = Float.valueOf(value);
            mv.visitLdcInsn(key);
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
        }

        @Override
        public Class<?> type() {
            return Float.class;
        }
    },
    DoubleType {
        @Override
        public void apply(MethodVisitor mv, String value) throws NumberFormatException {
            Double key = Double.valueOf(value);
            mv.visitLdcInsn(key);
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
        }

        @Override
        public Class<?> type() {
            return Double.class;
        }
    },
    StringType {
        @Override
        public void apply(MethodVisitor mv, String value) throws NumberFormatException {
            mv.visitLdcInsn(value);
        }

        @Override
        public Class<?> type() {
            return String.class;
        }
    },
    BoolType {
        @Override
        public void apply(MethodVisitor mv, String value) throws NumberFormatException {
            if (value.equals("true")) {
                mv.visitInsn(ICONST_1);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
            } else if (value.equals("false")) {
                mv.visitInsn(ICONST_0);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
            }
            throw new NumberFormatException("'" + value + "'并非布尔类型");
        }

        @Override
        public Class<?> type() {
            return Boolean.class;
        }
    },
    ListType {
        @Override
        public void apply(MethodVisitor mv, String value) throws NumberFormatException {

        }

        @Override
        public Class<?> type() {
            return List.class;
        }
    };

    public abstract void apply(MethodVisitor mv, String value) throws NumberFormatException;

    public abstract Class<?> type();
}